<?php
/*
 *Copyright (C), WhiteBlue
 *File name: model.php
 *Author: Version: 2015.3.9
 *Description: orm框架的简单实现(施工中)
 */

namespace core\main;

use PDO;

abstract class model
{
    protected $pk;//主键
    protected $relationMap;
    protected $DB;
    protected $tableName;
    protected $database;
    protected $ID;
    protected $modifyMap;//是否修改
    protected $isLoad = false;

    public function __construct($id = null, $pk = 'id')
    {
        $link = 'mysql:host=' . config('url') . ';port=' . config('port') . ';dbname=' . config('dbname');
        $this->DB = new PDO($link, 'root', '');
        $this->tableName = $this->getTableName();
        $this->relationMap = $this->getRelationMap();
        $this->pk = $pk;
        if (isset($id)) {
            $this->ID = $id;
            $this->load();
        }
    }

    abstract protected function getTableName();

    abstract protected function getRelationMap();


    //装载对象
    private function load()
    {
        if (isset($this->ID)) {
            $sql = "SELECT ";
            foreach ($this->relationMap as $key => $value) {
                $sql .= $key . ',';
            }
            $sql = substr($sql, 0, strlen($sql) - 1);
            $sql .= " FROM " . $this->tableName . " WHERE " . $this->pk . " = " . $this->ID;
            $result = $this->DB->query($sql);
            $result = mysqli_fetch_array($result);
            foreach ($result as $key => $value) {
                if (isset($this->relationMap[$key])) {
                    $member = $this->relationMap[$key];
                    if (property_exists($this, $member)) {
                        if (is_numeric($member)) {
                            eval('$this->' . $member . ' = ' . $value . ';');
                        } else {
                            eval('$this->' . $member . ' = "' . $value . '";');
                        }
                    }
                }
            }
        }
        $this->is_load = true;
    }

    //删除对象
    public function delete()
    {
        if (isset($this->ID)) {
            $sql = "DELETE FROM " . $this->tableName . " WHERE " . $this->pk . " = " . $this->ID;
            $this->DB->exec($sql);
        }
    }

    //setter和getter
    public function __call($method, $param)
    {
        $type = substr($method, 0, 3);
        $member = substr($method, 3);
        switch ($type) {
            case 'get':
                return $this->getMember($member);
                break;
            case 'set': {
                return $this->setMember($member, $param[0]);
            }
        }
        return false;
    }

    public function setMember($key, $value)
    {
        if (is_numeric($key)) {
            eval('$this->' . $key . ' = ' . $value . ';');
        } else {
            eval('$this->' . $key . ' = "' . $value . '";');
        }
        $this->modifyMap[$key] = 1;

    }

    public function getMember($key)
    {
        if (!$this->isLoad) {
            $this->Load();
        }
        if (property_exists($this, $key)) {
            eval('$res = $this->' . $key . ';');
            return $this->$key;
        }
        return false;
    }

    //新建或更新数据
    public function save()
    {
        if (isset($this->_ID)) {
            $sql = "UPDATE " . $this->tableName . " SET ";
            foreach ($this->relationMap as $key => $value) {
                if (array_key_exists($key, $this->modifyMap)) {
                    $val = null;
                    eval('$val = $this->' . $key . ';');
                    $sql .= $key . " = " . $val . ' ';
                }
            }
            $sql .= 'WHERE ' . $this->pk . ' = ' . $this->_ID;
        } else {
            $sql = "INSERT INTO " . $this->tableName . "(";
            $field = '';
            $values = '';
            foreach ($this->relationMap as $key => $value) {
                if (array_key_exists($key, $this->modifyMap)) {
                    $val = null;
                    eval('$val = $this->' . $key . ';');
                    $field .= $key . ',';
                    $values .= "'" . $val . "'" . ',';
                }
            }
            $field = substr($field, 0, strlen($field) - 1);
            $values = substr($values, 0, strlen($values) - 1);
            $sql= $sql . $field . ") VALUES (" . $values . ")";
        }
        $this->DB->query($sql);
    }

    public function paginate($pageSize, $sql, $page = 0)
    {
        $sql0 = 'SELECT count(' . $this->pk . ') FROM ' . $this->tableName . ';';
        $all = $this->query($sql0)->fetch();
        $page_all = ceil($all[0] / $pageSize);
        $sql0 = $sql . ' limit ' . $page * $pageSize . ',' . ($page + 1) * $pageSize;
        $back = $this->query($sql0)->fetchAll();
        return array('all' => $page_all,
            'current' => $page,
            'array' => $back
        );
    }


    public function query($sql)
    {
        return $this->DB->query($sql);
    }

    public function exec($sql)
    {
        return $this->DB->exec($sql);
    }

    public function find($sql)
    {
        return $this->DB->query($sql)->fetchAll();
    }

}